<?php
/**
 * 商品
 *
 * @author birdy <freebirdy@foxmail.com>
 * @link http://www.aiyuangong.com
 */
namespace app\seller\model;

use think\Model;

class Goods extends Model
{
    // 指定表名,不含前缀
    protected $name = 'goods';
    
    const STATE1 = 1;       // 出售中
    const STATE0 = 0;       // 下架
    const STATE10 = 10;     // 违规
    const VERIFY1 = 1;      // 审核通过
    const VERIFY0 = 0;      // 审核失败
    const VERIFY10 = 10;    // 等待审核
    
    /**
     * 出售中的商品列表 卖家中心使用
     *
     * @param array $condition 条件
     * @param array $field 字段
     * @param string $page 分页
     * @param string $order 排序
     * @return array
     */
    public function getGoodsCommonOnlineList($condition, $field = '*', $page = 1, $limit = 99999, $order = "id desc") {
        $condition['goods_state']   = self::STATE1;
        $condition['goods_verify']  = self::VERIFY1;
        return $this->getGoodsCommonList($condition, $field, $page, $limit, $order);
    }
    
    /**
     * 仓库中的商品列表 卖家中心使用
     *
     * @param array $condition 条件
     * @param array $field 字段
     * @param string $page 分页
     * @param string $order 排序
     * @return array
     */
    public function getGoodsCommonOfflineList($condition, $field = '*', $page = 1, $limit = 99999, $order = "id desc") {
        $condition['goods_state']   = self::STATE0;
        $condition['goods_verify']  = self::VERIFY1;
        return $this->getGoodsCommonList($condition, $field, $page, $limit, $order);
    }
    
    /**
     * 商品列表 卖家中心使用
     *
     * @param array $condition 条件
     * @param array $field 字段
     * @param string $page 分页
     * @param string $order 排序
     * @return array
     */
    public function getGoodsCommonList($condition, $field = '*', $page = 1, $limit = 99999, $order = 'id desc') {
        $condition = $this->_getRecursiveClass($condition);
        return \think\Db::name('goods_common')->field($field)->where($condition)->order($order)->page($page, $limit)->select();
    }
    
    /**
      * 获得商品子分类的ID
      * @param array $condition
      * @return array
      */
    private function _getRecursiveClass($condition){
        if (isset($condition['gc_id']) && !is_array($condition['gc_id'])) {
            $gc_list = model('goods_class')->getGoodsClassForCacheModel();
            if (!empty($gc_list[$condition['gc_id']])) {
                $gc_id[] = $condition['gc_id'];
                $gcchild_id = empty($gc_list[$condition['gc_id']]['child']) ? array() : explode(',', $gc_list[$condition['gc_id']]['child']);
                $gcchildchild_id = empty($gc_list[$condition['gc_id']]['childchild']) ? array() : explode(',', $gc_list[$condition['gc_id']]['childchild']);
                $gc_id = array_merge($gc_id, $gcchild_id, $gcchildchild_id);
                $condition['gc_id'] = array('in', $gc_id);
            }
        }
        return $condition;
    }
    
    /**
     * 计算商品库存
     *
     * @param array $goods_list
     * @return array|boolean
     */
    public function calculateStorage($goods_list) {
        // 计算库存
        if (!empty($goods_list)) {
            $goodsid_array = [];
            foreach ($goods_list as $value) {
                $goodscommonid_array[] = $value['id'];
            }
            $goods_storage = $this->getGoodsList(['commonid' => ['in', $goodscommonid_array]], 'goods_storage,commonid,id,goods_storage_alarm');
            $storage_array = [];
            foreach ($goods_storage as $val) {
                if (!isset($storage_array[$val['commonid']])) {
                    $storage_array[$val['commonid']]['alarm'] = false;
                    $storage_array[$val['commonid']]['sum'] = 0;
                    $storage_array[$val['commonid']]['goods_id'] = 0;
                }
                if ($val['goods_storage_alarm'] != 0 && $val['goods_storage'] <= $val['goods_storage_alarm']) {
                    $storage_array[$val['commonid']]['alarm'] = true;
                }
                $storage_array[$val['commonid']]['sum'] += $val['goods_storage'];
                $storage_array[$val['commonid']]['goods_id'] = $val['id'];
            }
            return $storage_array;
        } else {
            return false;
        }
    }
    
    /**
     * 更新商品信息
     *
     * @param array $condition
     * @param array $update1
     * @param array $update2
     * @return boolean
     */
    public function editProduces($condition, $update1, $update2 = array()) {
        $update2 = empty($update2) ? $update1 : $update2;
        $goods_array = $this->getGoodsCommonList($condition, 'id');
        if (empty($goods_array)) {
            return true;
        }
        $commonid_array = array();
        foreach ($goods_array as $val) {
            $commonid_array[] = $val['id'];
        }
        $return1 = $this->editGoodsCommonById($update1, $commonid_array);
        $return2 = $this->editGoods($update2, array('commonid' => array('in', $commonid_array)));
        if ($return1 && $return2) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * 更新商品SUK数据
     *
     * @param array $update 更新数据
     * @param array $condition 条件
     * @return boolean
     */
    public function editGoods($update, $condition) {
        $goods_list = $this->getGoodsList($condition, 'id');
        if (empty($goods_list)) {
            return true;
        }
        $goodsid_array = array();
        foreach ($goods_list as $value) {
            $goodsid_array[] = $value['id'];
        }
        return $this->editGoodsById($update, $goodsid_array);
    }

    /**
     * 更新商品SUK数据
     * @param array $update
     * @param int|array $goodsid_array
     * @return boolean|unknown
     */
    public function editGoodsById($update, $goodsid_array) {
        if (empty($goodsid_array)) {
            return true;
        }
        $condition['id'] = array('in', $goodsid_array);
        $update['goods_edittime'] = time();
        $result = $this->where($condition)->update($update);
        if ($result) {
            foreach ((array)$goodsid_array as $value) {
                $this->_dGoodsCache($value);
            }
        }
        return $result;
    }
    
    /**
     * 更新商品数据
     * @param array $update
     * @param int|array $commonid_array
     * @return boolean|unknown
     */
    public function editGoodsCommonById($update, $commonid_array) {
        if (empty($commonid_array)) {
            return true;
        }
        $condition['id'] = array('in', $commonid_array);
        $result = \think\Db::name('goods_common')->where($condition)->update($update);
        if ($result) {
            foreach ((array)$commonid_array as $val) {
                $this->_dGoodsCommonCache($val);
            }
        }
        return $result;
    }
    
    /**
     * 更新未锁定商品信息
     *
     * @param array $condition
     * @param array $update1
     * @param array $update2
     * @return boolean
     */
    public function editProducesNoLock($condition, $update1, $update2 = array()) {
        $condition['goods_lock'] = 0;
        return $this->editProduces($condition, $update1, $update2);
    }
    
    /**
     * 商品下架
     * @param array $condition 条件
     * @return boolean
     */
    public function editProducesOffline($condition){
        $update = array('goods_state' => self::STATE0);
        return $this->editProducesNoLock($condition, $update);
    }
    
    /**
     * 商品上架
     * @param array $condition 条件
     * @return boolean
     */
    public function editProducesOnline($condition){
        $update = array('goods_state' => self::STATE1);
        // 禁售商品、审核失败商品不能上架。
        $condition['goods_state'] = self::STATE0;
        $condition['goods_verify'] = array('neq', self::VERIFY0);
        // 修改预约商品状态
        $update['is_appoint'] = 0;
        return $this->editProduces($condition, $update);
    }
    
    /**
     * 商品删除及相关信息
     *
     * @param   array $condition 列表条件
     * @return boolean
     */
    public function delGoodsAll($condition) {
        $goods_list = $this->getGoodsList($condition, 'id,commonid,store_id');
        if (empty($goods_list)) {
            return false;
        }
        $goodsid_array = array();
        $commonid_array = array();
        foreach ($goods_list as $val) {
            $goodsid_array[] = $val['id'];
            $commonid_array[] = $val['commonid'];
        }
        $commonid_array = array_unique($commonid_array);

        // 删除商品表数据
        $this->delGoods(array('id' => array('in', $goodsid_array)));
        // 删除商品公共表数据
        \think\Db::name('goods_common')->where(array('id' => array('in', $commonid_array)))->delete();
        // 删除商品图片表数据
        $this->delGoodsImages(array('commonid' => array('in', $commonid_array)));
        return true;
    }
    
    /**
     * 删除商品SKU信息
     *
     * @param array $condition
     * @return boolean
     */
    public function delGoods($condition) {
        $goods_list = $this->getGoodsList($condition, 'id,commonid,store_id');
        if (!empty($goods_list)) {
            $goodsid_array = array();
            // to do删除商品二维码
            foreach ($goods_list as $val) {
                $goodsid_array[] = $val['id'];
                @unlink(BASE_UPLOAD_PATH.DS.ATTACH_STORE.DS.$val['store_id'].DS.$val['id'].'.png');
                // 删除商品缓存
                $this->_dGoodsCache($val['id']);
                // 删除商品规格缓存
                $this->_dGoodsSpecCache($val['commonid']);
            }
            // 删除属性关联表数据
            \think\Db::name('goods_attr_index')->where(array('goods_id' => array('in', $goodsid_array)))->delete();
            // 删除商品浏览记录
            \think\Db::name('goods_browse')->where(array('goods_id' => array('in', $goodsid_array)))->delete();
            // 删除买家收藏表数据
            \think\Db::name('favorites')->where(array('fav_id' => array('in', $goodsid_array), 'fav_type' => 'goods'))->delete();
        }
        return $this->where($condition)->delete();
    }
    
    /**
     * 删除未锁定商品
     * @param unknown $condition
     */
    public function delGoodsNoLock($condition) {
        $condition['goods_lock'] = 0;
        $common_array = $this->getGoodsCommonList($condition, 'id', 0);
        $cids = get_arr_key($common_array, 'id');
        return $this->delGoodsAll(array('commonid' => array('in', $cids)));
    }
    
    /**
     * 删除商品图片表信息
     *
     * @param array $condition
     * @return boolean
     */
    public function delGoodsImages($condition) {
        $image_list = $this->getGoodsImageList($condition, 'commonid,color_id');
        if (empty($image_list)) {
            return true;
        }
        $result = \think\Db::name('goods_images')->where($condition)->delete();
        if ($result) {
            foreach ($image_list as $val) {
                $this->_dGoodsImageCache($val['commonid'] . '|' . $val['color_id']);
            }
        }
        return $result;
    }
    
    /**
     * 商品图片列表
     *
     * @param array $condition
     * @param array $order
     * @param string $field
     * @return array
     */
    public function getGoodsImageList($condition, $field = '*', $order = 'is_default desc,goods_image_sort asc') {
        return \think\Db::name('goods_images')->field($field)->where($condition)->order($order)->select();
    }
    
    /**
     * 商品SKU列表
     *
     * @param array $condition 条件
     * @param string $field 字段
     * @param string $group 分组
     * @param string $order 排序
     * @param int $page 分页
     * @param int $limit 限制
     * @param boolean $lock 是否锁定
     * @return array 二维数组
     */
    public function getGoodsList($condition, $field = '*', $group = '',$order = 'id desc', $page = 1, $limit = 99999, $lock = false) {
        $condition = $this->_getRecursiveClass($condition);
        return $this->field($field)->where($condition)->group($group)->order($order)->page($page, $limit)->lock($lock)->select();
    }
    
    /**
     * 删除商品公共缓存
     * @param int $goods_commonid
     * @return boolean
     */
    private function _dGoodsCommonCache($goods_commonid) {
        return \think\Cache::rm('goods_common_'.$goods_commonid);
    }
    
    /**
     * 删除商品缓存
     * @param int $goods_id
     * @return boolean
     */
    private function _dGoodsCache($goods_id) {
        return \think\Cache::rm('goods_'.$goods_id);
    }
    
    /**
     * 删除商品规格缓存
     * @param int $goods_commonid
     * @return boolean
     */
    private function _dGoodsSpecCache($goods_commonid) {
        return \think\Cache::rm('goods_spec'.$goods_commonid);
    }
    
    /**
     * 删除商品图片缓存
     * @param int $key ($goods_commonid .'|'. $color_id)
     * @return boolean
     */
    private function _dGoodsImageCache($key) {
        return \think\Cache::rm('goods_image'.$key);
    }
}
